package setting

import (
	"log"
	"os"
	"time"

	"gopkg.in/yaml.v3"
)

/*
config.yml配置文件
从 conf/config.yml 配置文件中读取应用、服务器、数据库和 Redis 的相关配置信息
*/
type App struct {
	JwtSecret string
	PageSize  int
	PrefixUrl string

	RuntimeRootPath string

	ImageSavePath  string
	ImageMaxSize   int
	ImageAllowExts []string

	ExportSavePath string
	QrCodeSavePath string
	FontSavePath   string

	LogSavePath string
	LogSaveName string
	LogFileExt  string
	TimeFormat  string
}

var AppSetting = &App{}

type Server struct {
	RunMode      string        `yaml:"run-mode"`
	HttpPort     int           `yaml:"http-port"`
	ReadTimeout  time.Duration `yaml:"read-timeout"`
	WriteTimeout time.Duration `yaml:"write-timeout"`
}

var ServerSetting = &Server{}

type Database struct {
	Type        string
	User        string
	Password    string
	Host        string
	Name        string
	TablePrefix string
}

var DatabaseSetting = &Database{}

type Redis struct {
	Host        string
	Password    string
	MaxIdle     int
	MaxActive   int
	IdleTimeout time.Duration
}

var RedisSetting = &Redis{}

type Wechat struct {
	AppID          string
	AppSecret      string
	Token          string
	EncodingAESKey string
}

var WechatSetting = &Wechat{}

var yamlCfg map[string]interface{}

// Setup initialize the configuration instance
func Setup() {
	// 读取YAML配置
	if err := loadYamlConfig(); err != nil {
		log.Fatalf("Failed to load configuration: %v", err)
	}
}

// loadYamlConfig 加载YAML配置文件
func loadYamlConfig() error {
	// 读取config.yml
	yamlPath := "conf/config.yml"
	data, err := os.ReadFile(yamlPath)
	if err != nil {
		return err
	}

	yamlCfg = make(map[string]interface{})
	if err := yaml.Unmarshal(data, &yamlCfg); err != nil {
		return err
	}

	// 映射配置到结构体
	mapYamlTo("app", AppSetting)
	mapYamlTo("server", ServerSetting)
	mapYamlTo("database", DatabaseSetting)
	mapYamlTo("redis", RedisSetting)
	mapYamlTo("wechat", WechatSetting)

	// 转换单位
	AppSetting.ImageMaxSize = AppSetting.ImageMaxSize * 1024 * 1024
	ServerSetting.ReadTimeout = ServerSetting.ReadTimeout * time.Second
	ServerSetting.WriteTimeout = ServerSetting.WriteTimeout * time.Second
	RedisSetting.IdleTimeout = RedisSetting.IdleTimeout * time.Second

	return nil
}

// mapYamlTo 将YAML配置映射到结构体
func mapYamlTo(section string, v interface{}) {
	if sectionData, ok := yamlCfg[section]; ok {
		data, err := yaml.Marshal(sectionData)
		if err != nil {
			log.Fatalf("Failed to marshal YAML section %s: %v", section, err)
		}
		if err := yaml.Unmarshal(data, v); err != nil {
			log.Fatalf("Failed to unmarshal YAML section %s: %v", section, err)
		}
	} else {
		log.Printf("Section %s not found in YAML config", section)
	}
}
